package be.kuleuven.cs.mop.app.controllers;


import static junit.framework.Assert.*;

import java.util.HashMap;

import org.junit.*;

import be.kuleuven.cs.mop.TestEnvironment;
import be.kuleuven.cs.mop.app.controllers.TaskController;
import be.kuleuven.cs.mop.domain.exceptions.BusinessRuleTwoViolationExceptionTask;
import be.kuleuven.cs.mop.domain.exceptions.InvalidCurrentUserException;
import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.Task;
import be.kuleuven.cs.mop.domain.model.TaskStatus;
import be.kuleuven.cs.mop.domain.model.impl.Field;
import be.kuleuven.cs.mop.domain.model.impl.Schedule;



public class TaskControllerTest {
	
	private static TestEnvironment ENV;
	
	private static TaskController	ctrl;
	private static Task				task;
	
	@Before
	public void setUp() throws Exception {
		ENV = TestEnvironment.newInstance();
		
		ctrl	= ENV.controllers.getControllerTasks();
		task	= ctrl.createTask(
				ENV.schedule1,
				null,
				new HashMap<String, Field>(),
				ENV.testTaskType);
	}
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {}
	
	@After
	public void tearDown() throws Exception {}
	
	@AfterClass
	public static void tearDownAfterClass() throws Exception {}
	
	@Test(expected=TaskManagerException.class)
	public void testCreateTaskInvalidNull()
			throws InvalidCurrentUserException, TaskManagerException {
		ctrl.createTask(null, null, null, null);
	}
	
	@Test
	public void testCreateTaskValid()
			throws InvalidCurrentUserException, TaskManagerException {
		final Task t = ctrl.createTask(
				new Schedule(ENV.datum1, ENV.datum2, ENV.duration),
				null,
				new HashMap<String, Field>(),
				ENV.testTaskType);
		assertTrue(ctrl.getTasks().contains(t));
	}
	
	@Test(expected=TaskManagerException.class)
	public void testModifyTaskInvalidNull()
			throws InvalidCurrentUserException, TaskManagerException {
		try {
			ctrl.modifyTask(task, null, null, null);
		} catch (final BusinessRuleTwoViolationExceptionTask e) {
			assertFalse(true);
		}
	}
	
	@Test
	public void testModifyTaskValid()
			throws InvalidCurrentUserException, TaskManagerException {
		final Task t = ctrl.createTask(
				new Schedule(ENV.datum1, ENV.datum2, ENV.duration),
				null,
				new HashMap<String, Field>(),
				ENV.testTaskType);
		
		assertTrue(t.getSchedule().getDuration() == ENV.duration);
		assertTrue(t.getDependencies().isEmpty());
		
		try {
			ctrl.modifyTask(t,
					new Schedule(t.getSchedule().getStartDate(),
							t.getSchedule().getDeadline(),
							(20 * 60000)),
					null,
					new HashMap<String, Field>());
		} catch (final BusinessRuleTwoViolationExceptionTask e) {
			assertFalse(true);
		}
		
		assertTrue(t.getSchedule().getDuration() == (20 * 60000));
		assertTrue(t.getDependencies().isEmpty());
	}
	
	@Test(expected=NullPointerException.class)
	public void testRemoveTaskInvalidNull()
			throws InvalidCurrentUserException, TaskManagerException {
		ctrl.removeTask(null);
	}
	
	@Test
	public void testRemoveTaskValid()
			throws InvalidCurrentUserException, TaskManagerException {
		ctrl.removeTask(task);
		assertFalse(ctrl.getTasks().contains(task));
	}
	
	@Test
	public void testRemoveTaskRecursively() {
		//	TODO
	}
	
	@Test(expected=NullPointerException.class)
	public void testUpdateTaskStatusInvalidNull() {
		try {
			ctrl.updateTaskStatus(task, null);
		} catch (final NullPointerException e) {
			throw e;
		} catch (final Exception e) {
			assertFalse(true);
		}
	}
	
	@Test
	public void testUpdateTaskStatusValid() {
		try {
			ctrl.updateTaskStatus(task, TaskStatus.FAILED);
			assertTrue(task.getStatus().equals(TaskStatus.FAILED));
		} catch (final Exception e) {
			e.printStackTrace();
			assertFalse(true);
		}
	}
	
	@Test
	public void testUpdateTaskStatusRecursively() {
		//	TODO
	}
	
}